<template>
  <div>
    <PageWrapper contentBackground :dense="true" :contentFullHeight="true">
      <div class="header_button">
        <a-button type="primary" style="margin-right: 20px" @click="saveGraph">{{
          t('common.saveText')
        }}</a-button>
      </div>
      <div class="content">
        <div class="app-stencil" ref="stencilContainer" id="stencilContainer"> </div>
        <div class="app-content" ref="graphContainer" id="graphContainer"> </div>
      </div>
      <!-- 自定义标签弹窗 -->
      <Modal
        :title="t('routes.demo.workFlow.flowModelPage.customLabel')"
        v-model:visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        :maskClosable="false"
      >
        <div style="display: flex; justify-content: center; align-items: center">
          <Select v-model:value="title" default-value="成功" style="width: 60%">
            <SelectOption value="成功">{{
              t('routes.demo.workFlow.flowModelPage.success')
            }}</SelectOption>
            <SelectOption value="失败">{{
              t('routes.demo.workFlow.flowModelPage.fail')
            }}</SelectOption>
          </Select>
        </div>
      </Modal>
      <!-- 步骤属性 -->
      <Modal
        :title="t('routes.demo.workFlow.flowModelPage.stepProperty')"
        v-model:visible="stepVisible"
        @ok="handleOkStep"
        @cancel="handleCancelStep"
        :maskClosable="false"
      >
        <div style="height: 550px; overflow: auto" id="stepOption">
          <Tabs type="card" v-model:activeKey="activeKey">
            <TabPane key="1" :tab="t('routes.demo.workFlow.flowModelPage.basicProperty')">
              <Row>
                <Col :span="24">
                  <Form :model="form" :label-col="{ span: 8 }" :wrapper-col="{ span: 15 }">
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.code')">
                      <Input v-model:value="form.shortid" readOnly />
                    </FormItem>
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.name')">
                      <Input v-model:value="form.name" />
                    </FormItem>
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.workDescription')">
                      <Textarea
                        v-model:value="form.description"
                        :autosize="{ minRows: 3, maxRows: 5 }"
                      />
                    </FormItem>
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.HandleWay')">
                      <Select v-model:value="form.process">
                        <SelectOption :value="7">
                          {{ t('routes.demo.workFlow.flowModelPage.selectPrincipal') }}
                        </SelectOption>
                        <SelectOption :value="1">
                          {{ t('routes.demo.workFlow.flowModelPage.selectPrincipalInTemplate') }}
                        </SelectOption>
                      </Select>
                    </FormItem>
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.principal')">
                      <Select v-model:value="form.actor" :disabled="form.process == 7">
                        <SelectOption
                          v-for="(item, index) in personList"
                          :value="item.id"
                          :key="index"
                        >
                          {{ item.name }}
                        </SelectOption>
                      </Select>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check1">{{
                        t('routes.demo.workFlow.flowModelPage.adjustObject')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check2">{{
                        t('routes.demo.workFlow.flowModelPage.editObject')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check3">{{
                        t('routes.demo.workFlow.flowModelPage.addReferenceDocument')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check4">{{
                        t('routes.demo.workFlow.flowModelPage.downloadReferenceDocument')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check5">{{
                        t('routes.demo.workFlow.flowModelPage.noSelectPrincipal')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem label=" " :colon="false">
                      <Checkbox v-model:checked="form.check6">{{
                        t('routes.demo.workFlow.flowModelPage.mustAddObject')
                      }}</Checkbox>
                    </FormItem>
                    <FormItem :label="t('routes.demo.workFlow.flowModelPage.multiStepJudge')">
                      <Select v-model:value="form.routerOnEntry">
                        <SelectOption :value="1">
                          {{ t('routes.demo.workFlow.flowModelPage.and') }}
                        </SelectOption>
                        <SelectOption :value="0">
                          {{ t('routes.demo.workFlow.flowModelPage.or') }}
                        </SelectOption>
                      </Select>
                    </FormItem>
                  </Form>
                </Col>
              </Row>
            </TabPane>
            <TabPane key="2" tab="超期设定">
              <Form :labelCol="{ span: 6 }" :wrapperCol="{ span: 15 }" :model="overTimeSetting">
                <FormItem :label="t('routes.demo.workFlow.handleWay')">
                  <Select v-model:value="overTimeSetting.handleWay">
                    <SelectOption value="1">{{ t('routes.demo.workFlow.way1') }}</SelectOption>
                    <SelectOption value="2">{{ t('routes.demo.workFlow.way2') }}</SelectOption>
                  </Select>
                </FormItem>
                <FormItem :label="t('routes.demo.workFlow.overdueTime')">
                  <Row align="middle" :gutter="10">
                    <Col :span="8">
                      <Input
                        v-model:value="overTimeSetting.day"
                        :placeholder="t('routes.demo.workFlow.dayPlaceholder')"
                        :disabled="overTimeSetting.handleWay == '2'"
                      /> </Col
                    ><span>{{ t('routes.demo.workFlow.day') }}</span>
                    <Col :span="8">
                      <Input
                        v-model:value="overTimeSetting.hour"
                        :placeholder="t('routes.demo.workFlow.hourPlaceholder')"
                        :disabled="overTimeSetting.handleWay == '2'"
                      /> </Col
                    ><span>{{ t('routes.demo.workFlow.hour') }}</span>
                  </Row>
                </FormItem>
              </Form>
            </TabPane>
            <TabPane key="3" tab="消息设定">
              <Divider>超期消息设定</Divider>
              <Form :labelCol="{ span: 6 }" :wrapperCol="{ span: 15 }" :model="messageSetting">
                <FormItem :label="t('routes.demo.workFlow.overdueMessage')">
                  <RadioGroup v-model:value="messageSetting.overTime">
                    <Radio value="1">{{ t('common.yes') }}</Radio>
                    <Radio value="2">{{ t('common.no') }}</Radio>
                  </RadioGroup>
                </FormItem>
                <FormItem :label="t('routes.demo.workFlow.handleWay')">
                  <Select
                    v-model:value="messageSetting.overTimeWay"
                    :disabled="messageSetting.overTime == '2'"
                  >
                    <SelectOption value="1">{{ t('routes.demo.workFlow.way3') }}</SelectOption>
                    <SelectOption value="2">{{ t('routes.demo.workFlow.way4') }}</SelectOption>
                  </Select>
                </FormItem>
                <FormItem :label="t('routes.demo.workFlow.receiver')">
                  <Select
                    v-model:value="messageSetting.overTimeReceiver"
                    :disabled="messageSetting.overTime == '2'"
                  >
                    <SelectOption v-for="item in personList" :key="item.id" :value="item.id">{{
                      item.name
                    }}</SelectOption>
                  </Select>
                </FormItem>
              </Form>
              <Divider>完成消息设定</Divider>
              <Form :labelCol="{ span: 6 }" :wrapperCol="{ span: 15 }" :model="messageSetting">
                <FormItem :label="t('routes.demo.workFlow.overdueMessage')">
                  <RadioGroup v-model:value="messageSetting.finish">
                    <Radio value="1">{{ t('common.yes') }}</Radio>
                    <Radio value="2">{{ t('common.no') }}</Radio>
                  </RadioGroup>
                </FormItem>
                <FormItem :label="t('routes.demo.workFlow.handleWay')">
                  <Select
                    v-model:value="messageSetting.finishWay"
                    :disabled="messageSetting.finish == '2'"
                  >
                    <SelectOption value="1">{{ t('routes.demo.workFlow.way3') }}</SelectOption>
                    <SelectOption value="2">{{ t('routes.demo.workFlow.way4') }}</SelectOption>
                  </Select>
                </FormItem>
                <FormItem :label="t('routes.demo.workFlow.receiver')">
                  <Select
                    v-model:value="messageSetting.finishReceiver"
                    :disabled="messageSetting.finish == '2'"
                  >
                    <SelectOption v-for="item in personList" :key="item.id" :value="item.id">{{
                      item.name
                    }}</SelectOption>
                  </Select>
                </FormItem>
              </Form>
            </TabPane>
            <TabPane key="4" tab="表单权限">
              <Form :labelCol="{ span: 6 }" :wrapperCol="{ span: 15 }">
                <FormItem label="选择表单类别：">
                  <Select v-model:value="formPermission.formType" @change="changeFormType">
                    <SelectOption v-for="item in formTypeList" :key="item.id" :value="item.id">{{
                      item.name
                    }}</SelectOption>
                  </Select>
                </FormItem>
              </Form>
              <BasicTable @register="registerTable" :dataSource="formPermission.formAttr">
                <template #toolbar>
                  <a-button type="primary"> 权限生效 </a-button>
                </template>
                <!-- 是否浏览 -->
                <template #isView="{ record }">
                  <Checkbox v-model:checked="record.isView" />
                </template>
                <!-- 是否编辑 -->
                <template #isEdit="{ record }">
                  <Checkbox v-model:checked="record.isEdit" />
                </template>
                <!-- 是否必填 -->
                <template #isRequired="{ record }">
                  <Checkbox v-model:checked="record.isRequired" />
                </template>
              </BasicTable>
            </TabPane>
          </Tabs>
        </div>
      </Modal>
    </PageWrapper>
  </div>
</template>
<script lang="ts" setup>
  import { onMounted, ref } from 'vue';
  import { Graph, Addon, Shape } from '@antv/x6';
  import { PageWrapper } from '/@/components/Page';
  import {
    Modal,
    Select,
    SelectOption,
    Tabs,
    TabPane,
    Row,
    Col,
    Form,
    FormItem,
    Input,
    Checkbox,
    RadioGroup,
    Radio,
    Divider,
  } from 'ant-design-vue';
  import { useRoute, useRouter } from 'vue-router';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { addFlowTemplateApi, updateFlowTemplateApi } from '/@/api/demo/flow';
  import { Getallpersondto, GetAllBdDocType, getFileTypeTable } from '/@/api/demo/system';
  import { useMultipleTabStore } from '/@/store/modules/multipleTab';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { BasicTable, useTable } from '/@/components/Table';
  import { geFormColumns } from './flowData';

  const { t } = useI18n();

  // 超期设定
  const overTimeSetting = ref<any>({
    handleWay: '2', // 1:在建立工作流实例时允许修改超期时间 2:在建立工作流实例时不允许修改超期时间
    day: '', // 天
    hour: '', // 小时
  });

  // 消息设定
  const messageSetting = ref<any>({
    // 超期消息
    overTime: '2', // 1是 2否
    overTimeWay: '2', // 1:在建立工作流实例时允许修改消息接收人 2:在建立工作流实例时不允许修改消息接收人
    overTimeReceiver: '', // 消息接收人,如果有多个，用户id之间用逗号隔开
    // 完成消息
    finish: '2', // 1是 2否
    finishWay: '2', // 1:在建立工作流实例时允许修改消息接收人 2:在建立工作流实例时不允许修改消息接收人
    finishReceiver: '', // 消息接收人,如果有多个，用户id之间用逗号隔开
  });

  // 表单权限
  const formTypeList = ref([]); // 表单类别列表
  const formPermission = ref<any>({
    formType: '', // 表单类别
    formAttr: [], // 表单属性权限
  });

  const tabStore = useMultipleTabStore();
  const Textarea = Input.TextArea;
  const form: any = ref({
    shortid: '',
    name: '',
    description: '',
    process: 7,
    actor: '',
    check1: false,
    check2: false,
    check3: false,
    check4: false,
    check5: false,
    check6: false,
    routerOnEntry: 0,
  });

  const { createMessage } = useMessage();
  const { Edge } = Shape;
  const graphs: any = ref(null);
  const newArr: any = ref({});
  const title: any = ref('成功');
  const visible = ref(false);
  const stepVisible = ref(false);
  const newNodeArr: any = ref({});
  const updateShortId = ref('');
  const liststep: any = ref([]);
  const weblist: any = ref({});
  const mainwfdto: any = ref({});
  const savelist: any = ref({});
  const personList = ref<any>([]);
  const activeKey = ref('1');

  const route: any = useRoute();
  const router: any = useRouter();

  // 数据初始化
  const initData = () => {
    if (
      route.params.form !== undefined ||
      route.params.weblist !== undefined ||
      route.params.liststep !== undefined
    ) {
      mainwfdto.value = JSON.parse(route.params.form);
      weblist.value = JSON.parse(route.params.weblist);
      liststep.value = JSON.parse(route.params.liststep);
    }
  };

  // 人员数据
  Getallpersondto('').then((res) => {
    personList.value = res;
  });
  // 表单类型
  GetAllBdDocType().then((res) => {
    formTypeList.value = res;
  });
  // 表单类型切换
  const changeFormType = (formId) => {
    getFileTypeTable(formId).then((res) => {
      const newData = res.listDocQuality.map((item) => {
        return {
          prop: item.prop, // 表单属性的prop
          name: item.name, // 表单属性名称
          isView: false, // 是否允许浏览
          isEdit: false, // 是否允许编辑
          isRequired: false, // 是否必填
        };
      });
      formPermission.value.formAttr = newData;
    });
  };

  initData();
  // 生命周期
  onMounted(() => {
    initGraph();
    getDataList();
  });

  // 提取公共逻辑的函数
  const handleSaveOrUpdate = (isNew) => {
    weblist.value = graphs.value.toJSON();
    savelist.value = graphs.value.toJSON();

    const saveData = {
      mainwfdto: mainwfdto.value,
      weblist: weblist.value.cells,
      liststep: liststep.value,
      savelist: savelist.value,
    };

    const apiCall = isNew ? addFlowTemplateApi : updateFlowTemplateApi;
    const successMessage = isNew ? t('common.addSuccessText') : t('common.editSuccessText');

    apiCall(saveData);
    createMessage.success(successMessage);
    clearGraph();
    closeTabAndRedirect();
  };

  // 关闭当前 tab 并跳转
  const closeTabAndRedirect = () => {
    const targetKey = tabStore.tabList.find((item) => item.name === route.name).fullPath;
    tabStore.closeTabByKey(targetKey.toString(), router);
    router.push({ name: '流程模板' });
  };

  // 保存
  const saveGraph = () => {
    const isNew = weblist.value.length === 0;
    handleSaveOrUpdate(isNew);
  };

  // 获取数据列表
  const getDataList = () => {
    graphs.value.fromJSON(weblist.value);
  };

  // 清空图表数据
  const clearGraph = () => {
    liststep.value = [];
    mainwfdto.value = {};
    weblist.value = {};
    savelist.value = {};
  };

  const initGraph = () => {
    // 初始化画布
    let graphContainer: any = document.getElementById('graphContainer');
    const graph = new Graph({
      container: graphContainer,
      background: false, // 设置画布背景颜色
      grid: {
        type: 'dot', // 网格类型 'dot' | 'fixedDot' | 'mesh'
        size: 20, // 网格大小 10px
        visible: true, // 渲染网格背景
      },

      // 配置连线规则
      connecting: {
        // 路由将边的路径点 vertices 做进一步转换处理，并在必要时添加额外的点，然后返回处理后的点，默认值为 normal。
        router: {
          name: 'manhattan',
          args: {
            padding: 1,
          },
        },
        // 连接器将起点、路由返回的点、终点加工为 元素的 d 属性，决定了边渲染到画布后的样式，默认值为 normal。
        connector: {
          name: 'rounded',
          args: {
            radius: 8,
          },
        },
        anchor: 'center', // 当连接到节点时，通过 anchor 来指定被连接的节点的锚点，默认值为 center。
        connectionPoint: 'anchor', // 指定连接点，默认值为 boundary。
        allowBlank: false, //是否允许连接到画布空白位置的点
        // 当 snap 设置为 true 时连线的过程中距离节点或者连接桩 20px 时会触发自动吸附
        snap: {
          radius: 20,
        },
        // 连接的过程中创建新的边
        createEdge() {
          return new Edge({
            attrs: {
              line: {
                stroke: '#A2B1C3',
                strokeWidth: 2,
                targetMarker: {
                  name: 'block',
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        // 在移动边的时候判断连接是否有效，如果返回 false，当鼠标放开的时候，不会连接到当前元素，否则会连接到当前元素
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
      //拖动边时，是否高亮显示所有可用的节点
      highlighting: {
        //连线过程中，自动吸附到链接桩时被使用
        magnetAdsorbed: {
          name: 'stroke',
          args: {
            attrs: {
              fill: '#5F95FF',
              stroke: '#5F95FF',
            },
          },
        },
      },
      resizing: true, // 缩放节点，默认禁用。开启后可以对节点进行缩放
      rotating: true, // 旋转节点，默认禁用。开启后可以对节点进行旋转。
      // 点选/框选，默认禁用。创建画布时，通过以下配置开启选择交互，开启后可以通过点击或者套索框选节点。
      selecting: {
        enabled: true,
        rubberband: true, //是否启用框选，默认为 false。
        showNodeSelectionBox: true, // 是否显示节点的选择框，默认为 false。
      },
      snapline: {
        enabled: true, //对齐线
        tolerance: 10, //对齐精度
      },
      keyboard: true, // 键盘快捷键，默认禁用。
      clipboard: true, // 剪切板，默认禁用
      history: {
        enabled: true, //撤销/重做
        ignoreAdd: false, //是否忽略添加
        ignoreRemove: false, //是否忽略添加
        ignoreChange: false, //是否忽略属性变化
      },
      mousewheel: {
        enabled: true, // 支持滚动放大缩小
        zoomAtMousePosition: true, // 是否将鼠标位置作为中心缩放
        modifiers: 'ctrl', //修饰键('alt'、'ctrl'、'meta'、'shift')
        minScale: 0.5,
        maxScale: 3,
      },
      // panning: {
      //     enabled: true, // 支持画布平移
      // },
    });
    // 回显graph数据
    graphs.value = graph;
    // 初始化 stencil
    let sideOptions: any = document.getElementById('stencilContainer');
    const stencil = new Addon.Stencil({
      title: '全部组件',
      target: graph, //目标画布
      search: true, // 搜索选项
      placeholder: '搜索', //搜索文本框的 placeholder 文本
      notFoundText: '没有找到匹配项', //未匹配到搜索结果时的提示文本
      collapsable: true, //是否显示全局折叠/展开按钮
      stencilGraphWidth: 250, //模板画布宽度
      stencilGraphHeight: 300, //模板画布高度
      //分组信息
      groups: [
        {
          name: 'group1', // 分组名称
          title: '流程组件', // 分组标题，缺省时使用 `name`
        },
      ],
      layoutOptions: {
        columns: 2,
        columnWidth: 100,
        rowHeight: 70,
      },
    });
    sideOptions.appendChild(stencil.container);

    // 快捷键与事件
    // 复制
    graph.bindKey(['meta+c', 'ctrl+c'], () => {
      const cells = graph.getSelectedCells();
      if (cells.length) {
        graph.copy(cells);
      }
      return false;
    });
    // 剪切
    graph.bindKey(['meta+x', 'ctrl+x'], () => {
      const cells = graph.getSelectedCells();
      if (cells.length) {
        graph.cut(cells);
      }
      return false;
    });
    // 粘贴
    graph.bindKey(['meta+v', 'ctrl+v'], () => {
      if (!graph.isClipboardEmpty()) {
        const cells = graph.paste({ offset: 32 });
        graph.cleanSelection();
        graph.select(cells);
      }
      return false;
    });
    // 撤销
    graph.bindKey(['meta+z', 'ctrl+z'], () => {
      if (graph.history.canUndo()) {
        graph.history.undo();
      }
      return false;
    });
    // 重做
    graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
      if (graph.history.canRedo()) {
        graph.history.redo();
      }
      return false;
    });
    // 选择全部
    graph.bindKey(['meta+a', 'ctrl+a'], () => {
      const nodes = graph.getNodes();
      if (nodes) {
        graph.select(nodes);
      }
    });

    // 删除
    graph.bindKey(['backspace', 'delete'], () => {
      const cells = graph.getSelectedCells();
      if (cells.length) {
        graph.removeCells(cells);
      }
    });

    // 缩放
    graph.bindKey(['ctrl+1', 'meta+1'], () => {
      const zoom = graph.zoom();
      if (zoom < 1.5) {
        graph.zoom(0.1);
      }
    });
    graph.bindKey(['ctrl+2', 'meta+2'], () => {
      const zoom = graph.zoom();
      if (zoom > 0.5) {
        graph.zoom(-0.1);
      }
    });

    // 控制连接桩显示/隐藏
    const showPorts = (ports, show) => {
      for (let i = 0, len = ports.length; i < len; i = i + 1) {
        ports[i].style.visibility = show ? 'visible' : 'hidden';
      }
    };
    graph.on('node:mouseenter', () => {
      const ports = graphContainer.querySelectorAll('.x6-port-body');
      showPorts(ports, true);
    });
    graph.on('node:mouseleave', () => {
      const ports = graphContainer.querySelectorAll('.x6-port-body');
      showPorts(ports, false);
    });
    // 提取重复代码部分到一个函数中，简化属性赋值
    const updateFormFromNode = (node) => {
      const newObj = liststep.value.find((item) => item.shortid == node.id);
      const newAttrstr = newObj.attrstr.split('').map((element) => element === '1');

      Object.assign(form.value, {
        shortid: newObj.shortid,
        name: newObj.name,
        description: newObj.description,
        process: newObj.process,
        actor: newObj.actor,
        check1: newAttrstr[0],
        check2: newAttrstr[1],
        check3: newAttrstr[2],
        check4: newAttrstr[3],
        check5: newAttrstr[4],
        check6: newAttrstr[5],
        routerOnEntry: newObj.routerOnEntry,
      });
      overTimeSetting.value.handleWay = newObj.overTimeSetting.handleWay;
      overTimeSetting.value.day = newObj.overTimeSetting.day;
      overTimeSetting.value.hour = newObj.overTimeSetting.hour;
      messageSetting.value.overTime = newObj.messageSetting.overTime;
      messageSetting.value.overTimeWay = newObj.messageSetting.overTimeWay;
      messageSetting.value.overTimeReceiver = newObj.messageSetting.overTimeReceiver;
      messageSetting.value.finish = newObj.messageSetting.finish;
      messageSetting.value.finishWay = newObj.messageSetting.finishWay;
      messageSetting.value.finishReceiver = newObj.messageSetting.finishReceiver;
      formPermission.value.formType = newObj.formPermission.formType;
      formPermission.value.formAttr = newObj.formPermission.formAttr;
    };

    // 自定义边标签
    graph.on('edge:dblclick', (e: any) => {
      newArr.value = e.edge;
      if (e.edge.labels.length) {
        title.value = e.edge.labels[0].attrs.label.text;
      }
      visible.value = true;
    });

    // 连线新增事件
    graph.on('edge:added', (e) => {
      e.edge.setLabels([{ attrs: { label: { text: '成功' } } }]);
    });

    // 右击事件打开弹窗属性
    graph.on('node:contextmenu', (e: any) => {
      newNodeArr.value = e.node;
      updateShortId.value = e.node.id;
      stepVisible.value = true;
      updateFormFromNode(e.node);
    });

    // 节点添加事件
    graph.on('node:added', (e: any) => {
      const newNode = {
        shortid: e.node.id,
        name: e.node.label,
        description: '',
        process: 7,
        actor: '',
        attrstr: '000000',
        routerOnEntry: 0,
        overTimeSetting: {
          handleWay: '2',
          day: '',
          hour: '',
        },
        messageSetting: {
          overTime: '2',
          overTimeWay: '2',
          overTimeReceiver: '',
          finish: '2',
          finishWay: '2',
          finishReceiver: '',
        },
        formPermission: {
          formType: '',
          formAttr: [],
        },
      };
      liststep.value.push(newNode);
    });

    // 节点移除事件
    graph.on('node:removed', (e) => {
      liststep.value = liststep.value.filter((item) => item.shortid !== e.node.id);
    });

    // 初始化图形
    const ports = {
      groups: {
        top: {
          position: 'top',
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: '#5F95FF',
              strokeWidth: 1,
              fill: '#fff',
              style: {
                visibility: 'hidden',
              },
            },
          },
        },
        right: {
          position: 'right',
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: '#5F95FF',
              strokeWidth: 1,
              fill: '#fff',
              style: {
                visibility: 'hidden',
              },
            },
          },
        },
        bottom: {
          position: 'bottom',
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: '#5F95FF',
              strokeWidth: 1,
              fill: '#fff',
              style: {
                visibility: 'hidden',
              },
            },
          },
        },
        left: {
          position: 'left',
          attrs: {
            circle: {
              r: 4,
              magnet: true,
              stroke: '#5F95FF',
              strokeWidth: 1,
              fill: '#fff',
              style: {
                visibility: 'hidden',
              },
            },
          },
        },
      },
      items: [
        {
          group: 'top',
        },
        {
          group: 'right',
        },
        {
          group: 'bottom',
        },
        {
          group: 'left',
        },
      ],
    };
    Graph.registerNode(
      'custom-rect',
      {
        inherit: 'rect',
        width: 70,
        height: 40,
        attrs: {
          body: {
            strokeWidth: 1,
            stroke: '#5F95FF',
            fill: '#EFF4FF',
          },
          text: {
            fontSize: 12,
            fill: '#262626',
          },
        },
        ports: { ...ports },
      },
      true,
    );
    Graph.registerNode(
      'custom-polygon',
      {
        inherit: 'polygon',
        width: 66,
        height: 36,
        attrs: {
          body: {
            strokeWidth: 1,
            stroke: '#5F95FF',
            fill: '#EFF4FF',
          },
          text: {
            fontSize: 12,
            fill: '#262626',
          },
        },
        ports: {
          ...ports,
          items: [
            {
              group: 'top',
            },
            {
              group: 'bottom',
            },
          ],
        },
      },
      true,
    );
    Graph.registerNode(
      'custom-circle',
      {
        inherit: 'circle',
        width: 45,
        height: 45,
        attrs: {
          body: {
            strokeWidth: 1,
            stroke: '#5F95FF',
            fill: '#EFF4FF',
          },
          text: {
            fontSize: 12,
            fill: '#262626',
          },
        },
        ports: { ...ports },
      },
      true,
    );

    Graph.registerNode(
      'custom-image',
      {
        inherit: 'rect',
        width: 52,
        height: 52,
        markup: [
          {
            tagName: 'rect',
            selector: 'body',
          },
          {
            tagName: 'image',
          },
          {
            tagName: 'text',
            selector: 'label',
          },
        ],
        attrs: {
          body: {
            stroke: '#5F95FF',
            fill: '#5F95FF',
          },
          image: {
            width: 26,
            height: 26,
            refX: 13,
            refY: 16,
          },
          label: {
            refX: 3,
            refY: 2,
            textAnchor: 'left',
            textVerticalAnchor: 'top',
            fontSize: 12,
            fill: '#fff',
          },
        },
        ports: { ...ports },
      },
      true,
    );
    const star = graph.createNode({
      shape: 'custom-circle',
      label: '开始',
    });
    const end = graph.createNode({
      shape: 'custom-circle',
      label: '结束',
    });
    const process = graph.createNode({
      shape: 'custom-rect',
      attrs: {
        body: {
          rx: 6,
          ry: 6,
        },
      },
      label: '可选过程',
    });
    // const judge = graph.createNode({
    //   shape: 'custom-polygon',
    //   attrs: {
    //     body: {
    //       refPoints: '0,10 10,0 20,10 10,20',
    //     },
    //   },
    //   label: '决策',
    // });
    stencil.load([star, end, process], 'group1');
  };

  // 标签弹窗
  const handleOk = () => {
    if (newArr.value.labels.length == 0) {
      newArr.value.setLabels([{ attrs: { label: { text: title.value } } }]);
    } else {
      newArr.value.setLabels([{ attrs: { label: { text: title.value } } }]);
    }
    handleCancel();
  };
  const handleCancel = () => {
    title.value = '成功';
    visible.value = false;
  };

  const handleOkStep = () => {
    const updatedStep = liststep.value.find((element) => element.shortid === updateShortId.value);

    if (updatedStep) {
      const {
        name,
        shortid,
        description,
        process,
        actor,
        check1,
        check2,
        check3,
        check4,
        check5,
        check6,
        routerOnEntry,
      } = form.value;

      updatedStep.label = name;
      updatedStep.shortid = shortid;
      updatedStep.name = name;
      updatedStep.description = description;
      updatedStep.process = process;
      updatedStep.actor = actor;

      updatedStep.attrstr = [check1, check2, check3, check4, check5, check6]
        .map(Boolean)
        .map(Number)
        .join('');

      updatedStep.routerOnEntry = routerOnEntry;
      newNodeArr.value.label = form.value.name;
      updatedStep.overTimeSetting.handleWay = overTimeSetting.value.handleWay;
      updatedStep.overTimeSetting.day = overTimeSetting.value.day;
      updatedStep.overTimeSetting.hour = overTimeSetting.value.hour;
      updatedStep.messageSetting.overTime = messageSetting.value.overTime;
      updatedStep.messageSetting.overTimeWay = messageSetting.value.overTimeWay;
      updatedStep.messageSetting.overTimeReceiver = messageSetting.value.overTimeReceiver;
      updatedStep.messageSetting.finish = messageSetting.value.finish;
      updatedStep.messageSetting.finishWay = messageSetting.value.finishWay;
      updatedStep.messageSetting.finishReceiver = messageSetting.value.finishReceiver;
      updatedStep.formPermission.formType = formPermission.value.formType;
      updatedStep.formPermission.formAttr = formPermission.value.formAttr;
    }

    // 修改节点名称
    handleCancelStep();
  };

  const handleCancelStep = () => {
    stepVisible.value = false;
    Object.assign(form.value, {
      shortid: '',
      name: '',
      description: '',
      process: 7,
      actor: '',
      routerOnEntry: 0,
      check1: false,
      check2: false,
      check3: false,
      check4: false,
      check5: false,
      check6: false,
    });
    overTimeSetting.value.handleWay = '2';
    overTimeSetting.value.day = '';
    overTimeSetting.value.hour = '';
    messageSetting.value.overTime = '2';
    messageSetting.value.overTimeWay = '2';
    messageSetting.value.overTimeReceiver = '';
    messageSetting.value.finish = '2';
    messageSetting.value.finishWay = '2';
    messageSetting.value.finishReceiver = '';
    formPermission.value.formType = '';
    formPermission.value.formAttr = [];
    activeKey.value = '1';

    // 避免直接操作 DOM
    // 如果需要滚动，可以考虑使用 Vue 的 ref 来访问该元素
    const stepOption = document.getElementById('stepOption');
    if (stepOption) {
      stepOption.scrollTop = 0;
    }
  };

  // 初始化表格
  const [registerTable, { getDataSource }] = useTable({
    columns: geFormColumns(),
    bordered: true,
    showIndexColumn: false,
    showTableSetting: false, // 显示表格设置工具
    tableSetting: { fullScreen: true }, // 表格设置工具配置
    pagination: { pageSize: 20, pageSizeOptions: ['20', '40', '60', '80'], defaultPageSize: 20 },
    scroll: { y: 200 },
    canResize: true,
    rowKey: 'prop',
  });
</script>

<style lang="less" scoped>
  ::v-deep(.ant-form-item) {
    margin-bottom: 10px !important;
  }

  .header_button {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    height: 50px;
    margin-top: 10px;
    box-shadow: 0 0 10px 1px #e9e9e9;
  }

  .content {
    font-family: sans-serif;
    display: flex;
    margin-top: 10px;
  }

  .app-stencil {
    width: 250px;
    height: 750px;
    border: 1px solid #f0f0f0;
    position: relative;
  }

  .app-content {
    flex: 1;
    width: 100%;
    height: 750px;
    margin-left: 8px;
    margin-right: 8px;
    box-shadow: 0 0 10px 1px #e9e9e9;
  }

  .x6-widget-stencil {
    background-color: #fff;
  }

  .x6-widget-stencil-title {
    background-color: #fff;
  }

  .x6-widget-stencil-group-title {
    background-color: #fff !important;
  }

  .x6-widget-transform {
    margin: -1px 0 0 -1px;
    padding: 0;
    border: 1px solid #239edd;
  }

  .x6-widget-transform > div {
    border: 1px solid #239edd;
  }

  .x6-widget-transform > div:hover {
    background-color: #3dafe4;
  }

  .x6-widget-transform-active-handle {
    background-color: #3dafe4;
  }

  .x6-widget-transform-resize {
    border-radius: 0;
  }

  .x6-widget-selection-inner {
    border: 1px solid #239edd;
  }

  .x6-widget-selection-box {
    opacity: 0%;
  }
</style>
